// https://developer.qiniu.com/kodo/1731/api-overview
const qiniu = require('qiniu') 
const log = require('../log')
const packageJson = require('../package.json')

const UP = {}

// 七牛云 response code  https://developer.qiniu.com/kodo/3928/error-responses
UP.code = {
  400: '请求报文格式错误',
  401: '认证授权失败',
  404: '资源不存在',
  405: '请求方式错误',
  406: '上传的数据 CRC32 校验错误',
  413: '请求资源大小大于指定的最大值',
  419: '用户账号被冻结',
  478: '镜像回源失败',
  502: '错误网关',
  503: '服务端不可用',
  504: '服务端操作超时',
  573: '单个资源访问频率过高',
  579: '上传成功但是回调失败',
  599: '服务端操作失败',
  608: '资源内容被修改',
  612: '指定资源不存在或已被删除',
  614: '目标资源已存在',
  630: '已创建的空间数量达到上限，无法创建新空间',
  631: '指定空间不存在',
  640: '调用列举资源(list)接口时，指定非法的marker参数',
  701: '在断点续上传过程中，后续上传接收地址不正确或ctx信息已过期'
}


// 检验必填配置项
UP.check = (options) => {
  log.yellow(`[${packageJson.name}] CDN >> Qiniu Cloud Kodo ...`)
  let isError = false
  if (!options.accessKey) {
    isError = true
    log.red(`[${packageJson.name}] accessKey not found in options.kodo`)
  }
  if (!options.secretKey) {
    isError = true
    log.red(`[${packageJson.name}] secretKey not found in options.kodo`)
  }
  if (!options.bucket) {
    isError = true
    log.red(`[${packageJson.name}] bucket not found in options.kodo`)
  }
  if (isError) {
    return false
  }
  return true
}

/**
 * 获取七牛token
 * @param {*} options 
 */
UP.token = (options) => {
  const putPolicy = new qiniu.rs.PutPolicy({ scope: options.bucket })
  const accessKey = options.accessKey
  const secretKey = options.secretKey
  const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
  const uploadToken = putPolicy.uploadToken(mac)
  return uploadToken
}

/**
 * 上传
 * @param {String} uploadPath 上传路径
 * @param {String} localPath 本地文件路径
 * @param {Object} options 配置项 accessKey, secretKey, bucket
 */
UP.put = async(uploadPath, localPath, options) => {
  const token = UP.token(options) // 生成上传 Token
  const formUploader = new qiniu.form_up.FormUploader(options)
  const putExtra = new qiniu.form_up.PutExtra()
  try {
    const result = await new Promise((resolve, reject) => {
      formUploader.putFile(token, uploadPath, localPath, putExtra, (respErr, respBody, respInfo) => {
        if (respErr) {
          reject(respErr)
        } else if (respInfo && respInfo.statusCode == 200) {
          log.green(`Upload Success => ${uploadPath}`)
          resolve(respInfo)
        } else {
          reject(respInfo)
        }
      })
    })
  } catch (err) {
    log.red(`[${packageJson.name}] Upload Error => ${uploadPath}`)
    return err
  }
  return null
}

module.exports = UP
